package com.uinnova.product.eam.service.impl;

import com.binary.core.lang.StringUtils;
import com.binary.core.util.BinaryUtils;
import com.binary.jdbc.Page;
import com.uinnova.product.eam.comm.model.es.ArchReview;
import com.uinnova.product.eam.constant.ArchReviewState;
import com.uinnova.product.eam.model.cj.domain.*;
import com.uinnova.product.eam.model.cj.request.PlanModuleAnswerRequest;
import com.uinnova.product.eam.model.cj.vo.PlanChapterAnnotationVO;
import com.uinnova.product.eam.model.cj.vo.QuestionAnswerVO;
import com.uinnova.product.eam.model.constants.Constants;
import com.uinnova.product.eam.model.es.PlanProcessRelation;
import com.uinnova.product.eam.service.ArchReviewService;
import com.uinnova.product.eam.service.GTPlanModuleAnnotationService;
import com.uinnova.product.eam.service.PlanProcessRelationService;
import com.uinnova.product.eam.service.cj.dao.ArchReviewDao;
import com.uinnova.product.eam.service.cj.dao.ChapterContextDao;
import com.uinnova.product.eam.service.cj.dao.PlanModuleAnnotationDao;
import com.uinnova.product.eam.service.cj.service.PlanChapterInstanceService;
import com.uinnova.product.eam.service.cj.service.PlanDesignInstanceService;
import com.uinnova.product.eam.service.exception.BusinessException;
import com.uinnova.product.eam.vo.ArchReviewRes;
import com.uino.api.client.permission.IUserApiSvc;
import com.uino.bean.permission.base.SysUser;
import com.uino.bean.permission.query.CSysUser;
import com.uino.util.sys.SysUtil;
import lombok.extern.log4j.Log4j2;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 方案批注service实现-国投定制
 *
 * @author zhaoxin
 * @since 2022-3-1 20:40:43
 */
@Service
@Log4j2
public class GTPlanModuleAnnotationServiceImpl implements GTPlanModuleAnnotationService {

    private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    @Resource
    private ChapterContextDao chapterContextDao;

    @Resource
    private PlanModuleAnnotationDao planModuleAnnotationDao;

    @Resource
    private IUserApiSvc userApiSvc;

    @Autowired
    private ArchReviewDao archReviewDao;

    @Autowired
    private PlanDesignInstanceService planDesignInstanceService;
    @Autowired
    private PlanChapterInstanceService planChapterInstanceService;
    @Resource
    private ArchReviewService archReviewService;
    @Resource
    private PlanProcessRelationService planProcessRelationService;

    @Override
    public Page<PlanChapterAnnotationVO> findGTAnnotationList(PlanModuleAnswerRequest request) {
        if (request == null) {
            throw new BusinessException("请求参数不能为空!");
        }
        if (StringUtils.isBlank(request.getBusinessKey()) && request.getArchReviewId() == null) {
            throw new BusinessException("缺少参数");
        }
        ArchReview archReview;
        if (!StringUtils.isBlank(request.getBusinessKey())) {
            archReview = archReviewDao.getById(Long.valueOf(request.getBusinessKey()));
        } else {
            archReview = archReviewDao.getById(request.getArchReviewId());
        }
        String processInstanceId = "-";
        if (!StringUtils.isBlank(archReview.getProcessInstanceId())) {
            processInstanceId = archReview.getProcessInstanceId();
        }
        Assert.notNull(archReview, "未找到架构评审提交记录");

        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        // 250402 新增需求 如果是已完结的流程，评审结果为“同意” 需要查询方案设计资产相应版本对应的批注列表
        // 250402.1 查询流程状态 根据流程状态判断是否已完结
        ArchReviewRes archReviewRes = archReviewService.getState(processInstanceId);
        // 250402.2 如果是已完结的流程，评审结果为“同意” 根据流程id查询对应版本的方案id
        List<Long> planIds = archReview.getPlanIds();
        if (ArchReviewState.PASS.equals(archReviewRes.getState())) {
            List<PlanProcessRelation> planProcessRelations = planProcessRelationService.getByProcessInstanceId(processInstanceId);
            if (!BinaryUtils.isEmpty(planProcessRelations)) {
                planIds = planProcessRelations.stream().map(PlanProcessRelation::getPlanId).collect(Collectors.toList());
            }
        }
        queryBuilder.must(QueryBuilders.termsQuery("planId", planIds));
        queryBuilder.must(QueryBuilders.termQuery("taskDefinitionKey.keyword", processInstanceId));
        queryBuilder.must(QueryBuilders.termQuery("problem", false));
        queryBuilder.must(QueryBuilders.termQuery("delFlag", false));

        Page<PlanModuleAnnotationEntity> annotationPage = planModuleAnnotationDao.getSortListByQuery(request.getPageNum(), request.getPageSize(), queryBuilder, "createTime", false);
        List<PlanChapterAnnotationVO> annotations = new ArrayList<>();
        if (!CollectionUtils.isEmpty(annotationPage.getData())) {
            Map<Long, PlanDesignInstance> planMap = new HashMap<>();
            List<PlanDesignInstance> plans = planDesignInstanceService.getByIds(planIds);
            if (!CollectionUtils.isEmpty(plans)) {
                planMap = plans.stream().collect(Collectors.toMap(PlanDesignInstance::getId, Function.identity()));
            }
            CSysUser cdt = new CSysUser();
            cdt.setLoginCodes(annotationPage.getData().stream().map(PlanModuleAnnotationEntity::getCreatorCode).distinct().toArray(String[]::new));
            List<SysUser> sysUsers = userApiSvc.getSysUserByCdt(cdt);
            Map<String, SysUser> userMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(sysUsers)) {
                userMap = sysUsers.stream().collect(Collectors.toMap(SysUser::getLoginCode, Function.identity()));
            }

            for (PlanModuleAnnotationEntity annotationEntity : annotationPage.getData()) {
                PlanChapterAnnotationVO annotation = new PlanChapterAnnotationVO();
                annotation.setId(annotationEntity.getId());
                annotation.setAnnotation(annotationEntity.getAnnotationContent());
                annotation.setCreator(annotationEntity.getCreatorCode());
                annotation.setCreatorName(userMap.containsKey(annotationEntity.getCreatorCode()) ? userMap.get(annotationEntity.getCreatorCode()).getUserName() : "-");
                annotation.setPlanName(planMap.containsKey(annotationEntity.getPlanId()) ? planMap.get(annotationEntity.getPlanId()).getName() : "-");
                annotation.setPlanId(annotationEntity.getPlanId());
                annotation.setPlanChapterId(annotationEntity.getPlanChapterId());
                annotation.setPlanChapterContextId(annotationEntity.getPlanChapterModuleId());

                // 章节信息
                if (!BinaryUtils.isEmpty(annotationEntity.getPlanChapterId())) {
                    ChapterInstance chapterInstance = planChapterInstanceService.getPlanChapterInstance(annotationEntity.getPlanChapterId());
                    if (!BinaryUtils.isEmpty(chapterInstance) && !StringUtils.isEmpty(chapterInstance.getName()) && !chapterInstance.getDeleted()) {
                        String moduleName = chapterInstance.getName();
                        ChapterContext context = chapterContextDao.getById(annotationEntity.getPlanChapterId());
                        if (!BinaryUtils.isEmpty(context)
                                && !CollectionUtils.isEmpty(context.getModuleList())
                                && !BinaryUtils.isEmpty(annotationEntity.getPlanChapterModuleId())) {
                            ContextModule module = context.getModuleList().stream()
                                    .collect(Collectors.toMap(ContextModule::getId, Function.identity()))
                                    .get(annotationEntity.getPlanChapterModuleId());
                            if (module != null) {
                                PlanTemplateChapterData moduleDefinition = module.getModuleDefinition();
                                Integer moduleType = moduleDefinition.getType();
                                // 制品
                                int product = 1;
                                // 表格
                                int table = 2;
                                // 富文本
                                int richText = 3;
                                //清单制品
                                int dataSet = 4;
                                //附件
                                int appendix = 5;
                                if (moduleType == product) {
                                    moduleName = moduleName + Constants.SLASH + moduleDefinition.getProductName();
                                } else if (moduleType == table) {
                                    moduleName = moduleName + Constants.SLASH + moduleDefinition.getDataTableName();
                                } else if (moduleType == richText) {
                                    moduleName = moduleName + Constants.SLASH + moduleDefinition.getRichTextName();
                                } else if (moduleType == dataSet) {
                                    moduleName = moduleName + Constants.SLASH + moduleDefinition.getDataSetName();
                                } else if (moduleType == appendix) {
                                    moduleName = moduleName + Constants.SLASH + moduleDefinition.getAppendixName();
                                }
                            }
                        }
                        annotation.setModule(moduleName);
                    }
                }

                List<QuestionAnswerVO> answerList = annotationEntity.getAnswerList();
                if (CollectionUtils.isEmpty(answerList)) {
                    answerList = new ArrayList<>();
                }
                //最新回复
                if (!CollectionUtils.isEmpty(answerList)) {
                    annotation.setLatestAnswer(answerList.get(answerList.size() - 1).getAnswer());
                } else {
                    annotation.setLatestAnswer(Constants.CENTRE_LINE);
                }
                //动态
                List<PlanChapterAnnotationVO.Answer> answers = new ArrayList<>();
                for (int i = answerList.size() - 1; i >= 0; i--) {
                    PlanChapterAnnotationVO.Answer answer = new PlanChapterAnnotationVO.Answer();
                    answer.setCreator(answerList.get(i).getUsername());
                    answer.setAction("回复");
                    answer.setAnswer(answerList.get(i).getAnswer());
                    answer.setCreateTime(transDateFormat(answerList.get(i).getAnswerTime()));
                    answers.add(answer);
                }
                PlanChapterAnnotationVO.Answer createAnswer = new PlanChapterAnnotationVO.Answer();
                createAnswer.setCreator(getUserNameByLoginCode(annotationEntity.getCreatorCode()));
                createAnswer.setAction("创建");
                createAnswer.setCreateTime(transDateFormat(annotationEntity.getCreateTime()));
                answers.add(createAnswer);


                //仅批注创建人及审批提交人有回复权限
                String curUserLoginCode = SysUtil.getCurrentUserInfo().getLoginCode();
                annotation.setAnswerAuth(curUserLoginCode.equals(annotationEntity.getCreatorCode())
                        || curUserLoginCode.equals(archReview.getCreatorCode()));
                annotation.setAnswers(answers);
                annotations.add(annotation);
            }
        }
        // 重新控制分页
        Page<PlanChapterAnnotationVO> page = new Page<>();
        page.setPageNum(annotationPage.getPageNum());
        page.setPageSize(annotationPage.getPageSize());
        page.setTotalPages(annotationPage.getTotalPages());
        page.setTotalRows(annotationPage.getTotalRows());
        page.setData(annotations);
        return page;
    }

    private String transDateFormat(Long date) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat timeFormatter = new SimpleDateFormat("yyyyMMddHHmmss");
        try {
            return format.format(timeFormatter.parse(date.toString()));
        } catch (ParseException e) {
            log.error("时间转换异常:{}", e.getMessage());
            return null;
        }
    }

    private String getUserNameByLoginCode(String loginCode) {
        CSysUser cdt = new CSysUser();
        cdt.setLoginCodeEqual(loginCode);
        List<SysUser> sysUserList = userApiSvc.getSysUserByCdt(cdt);
        return CollectionUtils.isEmpty(sysUserList) ? loginCode : sysUserList.get(0).getUserName();
    }
}
